#pragma once
#include <iostream>
#include <string>
#include <strings.h>//bzero
#include <arpa/inet.h>//转网络字节序

#include <cstring>

#include <sys/types.h>//socket ,recvfrom        
#include <sys/socket.h>

#include <sys/socket.h>
#include <netinet/in.h>//字符串转in_addr_t
#include <arpa/inet.h>
#include <iostream>
using namespace std;

#include "Log.hpp"

Log lg;

string default_ip ="0.0.0.0";
uint16_t default_port =8080;

enum
{
    Socket_err = 1,
    Bind_err,
    RE_err
};

class UdpServer{
public:
    UdpServer(uint16_t port = default_port, string ip = default_ip)
        :_socketid(0)
        ,_ip(ip)
        ,_port(port)
    {}

    void Init()
    {   //1.创建udp socket 
        _socketid = socket(AF_INET,SOCK_DGRAM,0);
        if(_socketid <0)
        {
            lg(Fatal,"socket create is error, socket_id : %d",_socketid);
            exit(Socket_err);
        }
        //2.bind
        lg(Info,"socket create is succes, socket_id : %d",_socketid);
        //int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);

        struct sockaddr_in _obj;
        bzero(&_obj,sizeof(_obj));

        _obj.sin_family = AF_INET;
        _obj.sin_port = htons(_port);
        _obj.sin_addr.s_addr = inet_addr(_ip.c_str());

        int ret = bind(_socketid,(struct sockaddr*)&_obj,sizeof(_obj));
        if(ret<0)
        {
            lg(Fatal,"bind create is error : %d",ret);
            exit(Bind_err);
        }
        lg(Info,"bind create is succes , port:%d",_port);
    }

    void run()
    {
        char Buffer[1024];
        string temp;

        while(true)
        {
           //ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
           //struct sockaddr *src_addr, socklen_t *addrlen);

           struct sockaddr_in client;
           socklen_t len = sizeof(client);

           ssize_t Re_ret = recvfrom(_socketid,Buffer,sizeof(Buffer)-1,0,//接收
                (struct sockaddr*)&client,&len);
            if(Re_ret<0)
            {
                lg(Fatal,"bind create is error : %d",Re_ret);
                continue;
            }

            Buffer[Re_ret] = 0;//看成字符串
            temp = Buffer;
            cout<<temp<<endl;
            //ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
                      //const struct sockaddr *dest_addr, socklen_t addrlen);
            sendto(_socketid,temp.c_str(),temp.size(),0,(struct sockaddr*)&client,len);//发送
        }
    }

    ~UdpServer()
    {
        
    }
private:
    int _socketid;//网络文件描述符
    string _ip;//字符串形式ip地址
    uint16_t _port;//服务器进程的端口号
};